home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / news / inn1.000 / inn1.4sec-linux-src.tar / inn / frontends / encode.c < prev    next >
C/C++ Source or Header  |  1993-01-29  |  3KB  |  125 lines

  1. /*  $Revision: 1.3 $
  2. **  Produce a seven-bit printable encoding of stdin on stdout.
  3. **  From @(#)encode.c 1.3 5/15/85, distributed with B2.11 News.
  4. **
  5. **
  6. **  The encoding uses characters from 0x20 (' ') through 0x7A ('z').
  7. **  (That fits nicely into the UUCP 'f' protocol by Piet Beertema.) First,
  8. **  expand three eight-bit charcters into four six-bit ones.  Collect
  9. **  until we have 13, and spread the last one over the first 12, so that
  10. **  we have 12 6.5-bit characters.  Since there are very few half-bit
  11. **  machines, collect them into pairs, making six 13-bit characters.  We
  12. **  can do this as A * 91 + B where A and B are less then 91 after we add
  13. **  0x20 to make it printable.
  14. **
  15. **  And if you thought that was unclear, then we won't even get into the
  16. **  terminating conditions!
  17. */
  18. #include "configdata.h"
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #include "clibrary.h"
  22.  
  23.  
  24. /*
  25. **  These characters can't appear in normal output, so we use them to
  26. **  mark that the data that follows is the terminator.  The character
  27. **  immediately following this pair is the length of the terminator (which
  28. **  otherwise might be indeterminable)
  29. */
  30. #define ENDMARK1    ((90 * 91 + 90) / 91 + ' ')
  31. #define ENDMARK2    ((90 * 91 + 90) % 91 + ' ')
  32.  
  33. static char    Buffer[13];
  34. static int    Count;
  35.  
  36.  
  37. static void
  38. dumpcode(p, n)
  39.     register char    *p;
  40.     register int    n;
  41. {
  42.     register int    last;
  43.     register int    c;
  44.  
  45.     if (n == 13) {
  46.     n--;
  47.     last = p[12];
  48.     }
  49.     else if (n & 1)
  50.     last = 1 << (6 - 1);
  51.     else
  52.     last = 0;
  53.  
  54.     for (; n > 0; n -= 2) {
  55.     c = *p++ << 6;
  56.     c |= *p++;
  57.     if (last & (1 << (6 - 1)))
  58.         c |= (1 << 12);
  59.     last <<= 1;
  60.  
  61.     (void)putchar((c / 91) + ' ');
  62.     (void)putchar((c % 91) + ' ');
  63.     }
  64. }
  65.  
  66. static void
  67. flushout()
  68. {
  69.     (void)putchar(ENDMARK1);
  70.     (void)putchar(ENDMARK2);
  71.     (void)putchar(Count + ' ');
  72.     dumpcode(Buffer, Count);
  73. }
  74.  
  75.  
  76. static void
  77. encode(dest, n)
  78.     register char    *dest;
  79.     int            n;
  80. {
  81.     register char    *p;
  82.     register int    i;
  83.     register int    j;
  84.     char        b4[4];
  85.  
  86.     b4[0] = (dest[0] >> 2) & 0x3F;
  87.     b4[1] = ((dest[0] & 0x03) << 4) | ((dest[1] >> 4) & 0x0F);
  88.     b4[2] = ((dest[1] & 0x0F) << 2) | ((dest[2] >> 6) & 0x03);
  89.     b4[3] = (char)(n == 3 ? dest[2] & 0x3F : n);
  90.  
  91.     for (p = b4, i = Count, dest = &Buffer[i], j = 4; --j >= 0; i++) {
  92.     if (i == 13) {
  93.         dumpcode(Buffer, 13);
  94.         dest = Buffer;
  95.         i = 0;
  96.     }
  97.     *dest++ = *p++;
  98.     }
  99.     Count = i;
  100. }
  101.  
  102.  
  103. /* ARGSUSED0 */
  104. int
  105. main(ac, av)
  106.     int            ac;
  107.     char        *av[];
  108. {
  109.     register char    *p;
  110.     register int    c;
  111.     char        b3[3];
  112.  
  113.     for (p = b3; (c = getchar()) != EOF; ) {
  114.     *p++ = (char)c;
  115.     if (p == &b3[3]) {
  116.         encode(b3, 3);
  117.         p = b3;
  118.     }
  119.     }
  120.     encode(b3, p - b3);
  121.     flushout();
  122.     exit(0);
  123.     /* NOTREACHED */
  124. }
  125.